﻿//========================================================= 
/**@file ObjectPool.h
 * @brief 简单的对象池
 * 
 * @date 2016-07-02   09:58:08
 * @author Zhyioo 
 * @version 1.0
 */ 
//--------------------------------------------------------- 
#ifndef _LIBZHOUYB_OBJECTPOOL_H_
#define _LIBZHOUYB_OBJECTPOOL_H_
//--------------------------------------------------------- 
#include "../../base/ArgParser.h"

#include "../../container/container_helper.h"
using zhou_yb::container::list_helper;
//--------------------------------------------------------- 
namespace zhou_yb {
namespace extension {
namespace ability {
//--------------------------------------------------------- 
/// 用于一个驱动以句柄的方式返回多个对象的对象池
template<class T, class Alloc = simple_alloc<T> >
class ObjectPool
{
protected:
    /// 以创建的对象数
    size_t _count;
    /// 最近访问的句柄
    size_t _cacheIndex;
    /// 对象数据
    list_t<T*> _objs;
public:
    ObjectPool()
    {
        _count = 1;
        _cacheIndex = 0;

        _objs.push_back(NULL);
    }
    virtual ~ObjectPool()
    {
        Clean();
    }
    /// 创建一个对象并返回对应的句柄
    size_t CreateObject()
    {
        T* pObj = Alloc::allocate();
        Alloc::construct(pObj);

        size_t handle = _count++;
        _objs.push_back(pObj);
        return handle;
    }
    /// 获取指定句柄的对象
    T* InstanceOf(size_t handle)
    {
        if(_cacheIndex != 0 && handle == _cacheIndex)
            return _objs.front();

        typename list_t<T*>::iterator itr = list_helper<T*>::index_of(_objs, handle);
        if(itr == _objs.end())
            return NULL;
        T* pObj = (*itr);
        _cacheIndex = handle;
        _objs.front() = pObj;
        return pObj;
    }
    /// 删除指定句柄的对象
    bool DestoryObject(size_t handle)
    {
        typename list_t<T*>::iterator itr = list_helper<T*>::index_of(_objs, handle);
        if(itr == _objs.end())
            return false;

        // 当前缓存的对象被删除时,需要重置状态
        if(handle == _cacheIndex)
        {
            _cacheIndex = 0;
            _objs.front() = NULL;
        }

        T* pObj = (*itr);
        if(pObj == NULL)
            return false;

        Alloc::destroy(pObj);
        Alloc::deallocate(pObj);

        (*itr) = NULL;
        return true;
    }
    /// 清空对象池
    void Clean()
    {
        typename list_t<T*>::iterator itr;
        T* pObj = NULL;
        for(itr = _objs.begin(); itr != _objs.end(); ++itr)
        {
            pObj = (*itr);
            if(pObj != NULL)
            {
                Alloc::destroy(pObj);
                Alloc::deallocate(pObj);
            }
            (*itr) = NULL;
        }

        _objs.clear();
        _objs.push_back(NULL);
        _cacheIndex = 0;
        _count = 1;
    }
    /// 返回当前的最大句柄值
    inline size_t Max() const
    {
        return _count;
    }
};
//--------------------------------------------------------- 
/// 基于Ref<TInterface> 的对象池
template<class TInterface>
class RefObjectPool
{
protected:
    MapArguments<string, Ref<TInterface> > _objs;
    list_t<TInterface*> _pool;
public:
    virtual ~RefObjectPool()
    {
        Clean();
    }
    template<class T>
    Ref<T> CreateObject(const string& key)
    {
        Ref<TInterface> ref;
        if(_objs.Get(key, ref))
            return Ref<T>();

        T* pObj = new T();
        _pool.push_back(pObj);
        _objs.Put(key, *pObj);

        return (*pObj);
    }
    inline Ref<TInterface> Get(const string& key)
    {
        Ref<TInterface> ref;
        _objs.Get(key, ref);
        return ref;
    }
    bool Remove(const string& key)
    {
        Ref<TInterface> ref;
        if(!_objs.Get(key, ref))
            return false;
        _objs.Remove(key);

        TInterface* pObj = &(*ref);
        bool bRemove = list_helper<TInterface>::remove(_pool, pObj) > 0;
        if(bRemove)
        {
            delete pObj;
        }
        return bRemove;
    }
    inline size_t Count() const
    {
        return _pool.size();
    }
    void Clean()
    {
        typename list_t<TInterface*>::iterator itr;
        for(itr = _pool.begin(); itr != _pool.end(); ++itr)
        {
            delete (*itr);
        }
        _pool.clear();
    }
};
//--------------------------------------------------------- 
} // namespace ability
} // namespace extension
} // namespace zhou_yb
//--------------------------------------------------------- 
#endif // _LIBZHOUYB_OBJECTPOOL_H_
//========================================================= 
